package com.yinbw.interview;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.keywords.MySqlKeyWordsHandler;
import com.mybatisplus.common.controller.BaseController;

/**
 * @author young
 * Date 2023/2/16 17:56
 * Description: MybatisPlus自动生成代码
 */
public class MybatisPlusGenerate {
    //需要手动添加的信息
    public static final String database = "learningsummary"; //数据库名称
    public static final String tables = "questions"; //逆向工程的表名
    public static final String parentPackage = "com.yinbw.interview";//父包名
    public static final String relativePath = "/" + "interview" + "/src/main/java";//module名 + 指定输出目录
    //固定内容
    public static final String[] autoGenerateTable = new String[]{tables};//逆向工程的表名
    public static final String author = "yinbw  http://localhost:8080/swagger-ui/index.html";//生成的作者名字
    public static final String moduleName = "";//父包模块名
    public static final String url = "jdbc:mysql://localhost:3306/"+database+"?&useSSL=false&serverTimezone=Asia/Shanghai";
    public static final String username = "root";
    public static final String password = "root";
    public static final String entityTemplate = "templates/entity";
    public static final String controllerTemplate = "templates/controller";
    public static final String serviceTemplate = "templates/service";
    public static final String serviceImplTemplate = "templates/serviceImpl";
    public static final String mapperTemplate = "templates/mapper";
    public static final String xmlTemplate = "templates/xml";

    public static void main(String[] args) {

//        1.设置全局配置，共8个属性
        String projectPath = System.getProperty("user.dir"); //获取项目路径
        String filePath = projectPath + relativePath;  //java下的文件路径
        GlobalConfig globalConfig = new GlobalConfig.Builder()
                .outputDir(filePath)//指定输出目录，默认windows:D:// linux or mac : /tmp
                .author(author)//生成的作者名字，默认-作者
                .enableSwagger()//开启swagger，需要添加swagger依赖并配置，默认false
//                .enableKotlin()//开启Kotlin，未知，不要开启，默认false
//                .dateType(DateType.TIME_PACK)//时间策略，默认-DateType.TIME_PACK
//                .commentDate("yyyy年MM月dd日")//格式化时间格式，默认-yyyy-MM-dd
                .disableOpenDir()//关闭禁止打开输出目录，默认-true
                .fileOverride()//开启覆盖生成文件
                .build();

//        2.设置包配置，共11个属性
        PackageConfig packageConfig = new PackageConfig.Builder()
                .parent(parentPackage)//父包名。默认-com.baomidou
                .moduleName(moduleName)//父包模块名。默认-""
//                .entity("entity")//Entity 包名。默认-entity
//                .controller("controller")//Controller 包名。默认-controller
//                .service("service")//service 层包名。默认-service
//                .serviceImpl("service.impl")//Service Impl 包名。默认-service.impl
//                .mapper("mapper")//mapper层包名。默认-mapper
//                .xml("mapper.xml")//Mapper XML 包名。默认-mapper.xml
//                .other("other")//自定义文件包名。默认-other
//                路径配置信息。实际无需设置由其它包名组成
//                .pathInfo(Collections.singletonMap(OutputFile.xml, projectPath + "/qwe/src/main/java/qwe/com/mapper/mapping"))//mapper.xml文件
//                .packageInfo("")//包信息。实际无需设置由其它包信息组成
                .build();

/*        3.设置模板配置。共8个属性，disableEntity属性无需设置
        共3个模板引擎 VelocityTemplateEngine、BeetlTemplateEngine、FreemarkerTemplateEngine，默认使用第一个
        如果模板引擎是 freemarker，文件后缀名为 .ftl
        String templatePath = "/templates/mapper.xml.ftl";
        如果模板引擎是 velocity，文件后缀名为 .vm
        String templatePath = "/templates/mapper.xml.vm";
        如果模板引擎是 Beetl，文件后缀名为 .
        String templatePath = "/templates/mapper.xml.btl";
        */
        TemplateConfig templateConfig = new TemplateConfig.Builder()
//                .disable()//禁用所有模板
//                .disable(TemplateType.ENTITY) //禁用指定模板,可变参数
                .entity(entityTemplate)//entity模板路径(JAVA)
//                .entityKt("")//entityKt模板路径(kotlin)
                .controller(controllerTemplate)//controller层模板路径
                .service(serviceTemplate)//service模板路径
                .serviceImpl(serviceImplTemplate)//实现类模板路径
                .mapper(mapperTemplate)//mapper模板路径
//                .xml(xmlTemplate)//xml文件模板路路径
                .build();

//        4.注入配置,自定义配置一个Map对象
//        Map<String,Object> map = new HashMap<>();
//        map.put("name","young");
//        map.put("age","22");
//        map.put("sex","男");
//        map.put("description","深情不及黎治跃");
//        InjectionConfig injectionConfig = new InjectionConfig.Builder()
//                .beforeOutputFile()//输出文件之前消费者
//                .customMap(map)//自定义配置 Map 对象
//                .customFile()//自定义配置模板文件
//                .fileOverride()//开启覆盖生成文件
//                .build();

//        5.策略配置开始
        StrategyConfig strategyConfig = new StrategyConfig.Builder()
                .enableCapitalMode()//开启大写命名。默认false
//                .enableSkipView()//开启跳过视图。默认值:false
//                .disableSqlFilter()//禁用sql过滤。默认值:true，语法不能支持使用 sql 过滤表的话，可以考虑关闭此开关
//                .enableSchema()//启用schema。默认值:false，多 schema 场景的时候打开
                .addTablePrefix("t_","c_")//增加过滤表前缀
//                .addTableSuffix()//增加过滤表后缀
//                .addFieldPrefix()//增加过滤字段前缀
//                .addFieldSuffix()//增加过滤字段后缀
                //可指定表，无参数表示增加全部的表
                .addInclude(autoGenerateTable)//增加表匹配(内存过滤)。include 与 exclude 只能配置一项 ，支持正则匹配、例如 ^t_.* 所有 t_ 开头的表名
//                .addExclude()//指定排除的表名
//                .likeTable()//模糊表匹配(sql 过滤)。likeTable 与 notLikeTable 只能配置一项
//                .notLikeTable()//模糊表排除(sql 过滤)。likeTable 与 notLikeTable 只能配置一项

//                entity策略配置
                .entityBuilder()
//                .disableSerialVersionUID()禁用生成SerialVersionUID：默认true
//                .nameConvert(INameConvert)//名称转换实现
                .superClass(Model.class)//设置父类，如BaseEntity.class
//                .disableSerialVersionUID()//禁用生成 serialVersionUID	默认值:true
                .fileOverride()//覆盖已生成文件	默认值:false
//                .enableColumnConstant()//开启生成字段常量	默认值:false
                .enableChainModel()//开启链式模型,默认值:false
                .enableLombok()//开启 lombok 模型	默认值:false
                .enableRemoveIsPrefix()//开启 Boolean 类型字段移除 is 前缀
                .enableTableFieldAnnotation()//开启生成实体时生成字段注解,默认值:false
//                .enableActiveRecord()//开启 ActiveRecord 模型	默认值:false
//                .versionColumnName(String)()//乐观锁字段名(数据库字段)	versionColumnName与versionPropertyName二选一即可
//                .versionPropertyName(String)()//乐观锁属性名(实体)	versionColumnName与versionPropertyName二选一即可
//                .logicDeleteColumnName(String)()//逻辑删除字段名(数据库字段)	logicDeleteColumnName与logicDeletePropertyName二选一即可
//                .logicDeletePropertyName(String)()//逻辑删除属性名(实体)	logicDeleteColumnName与logicDeletePropertyName二选一即可
                .naming(NamingStrategy.underline_to_camel)//数据表映射实体命名策略：默认下划线转驼峰underline_to_camel
                .columnNaming(NamingStrategy.underline_to_camel)//表字段映射实体属性命名规则：默认null，不指定按照naming执行
//                .addSuperEntityColumns(String...)()//添加父类公共字段
//                .addIgnoreColumns(String...)()//添加忽略字段
//                .addTableFills()添加表字段填充
                .idType(IdType.AUTO)//全局主键类型
//                .convertFileName(ConverterFileName)//转换文件名称
                .formatFileName("%s")//格式化实体名称，%s取消首字母I
                .build()

//                controller策略配置
                .controllerBuilder()
                .superClass(BaseController.class)//设置父类	BaseController.class
                .fileOverride()//覆盖已生成文件	默认值:false
//                .enableHyphenStyle()开启驼峰转连字符，默认：false
                .enableRestStyle()//开启生成@RestController。默认值:false
//                .convertFileName(ConverterFileName)//转换文件名称
                .formatFileName("%sAction")//格式化文件名称
                .build()

//                service策略配置
                .serviceBuilder()
                .superServiceClass(IService.class)//设置 service 接口父类	BaseService.class
                .superServiceImplClass(ServiceImpl.class)//设置 service 实现类父类	BaseServiceImpl.class
                .fileOverride()//覆盖已生成文件	默认值:false
//                .convertServiceFileName(ConverterFileName)//转换 service 接口文件名称
//                .convertServiceImplFileName(ConverterFileName)//转换 service 实现类文件名称
                .formatServiceFileName("%sService")//格式化 service 接口文件名称
                .formatServiceImplFileName("%sServiceImpl")//格式化 service 实现类文件名称
                .build()

//                mapper策略配置
                .mapperBuilder()
                .superClass(BaseMapper.class)//设置父类	BaseMapper.class
                .fileOverride()//覆盖已生成文件	默认值:false
                .enableMapperAnnotation()//开启mapper注解。默认值:false
                .enableBaseResultMap()//启用 BaseResultMap 生成。默认值:false
                .enableBaseColumnList()//启用 BaseColumnList	默认值:false
//                .cache(缓存类.class)设置缓存实现类。如MyMapperCache.class
//                .convertMapperFileName(ConverterFileName)//转换 mapper 类文件名称
//                .convertXmlFileName(ConverterFileName)//转换 xml 文件名称
                .formatMapperFileName("%sMapper")//格式化 mapper 文件名称
                .formatXmlFileName("%sMapper")//格式化 xml 实现类文件名称
                .build();

//        6.配置数据源
//        MySqlQuery mySqlQuery = new MySqlQuery() {
//            @Override
//            public String[] fieldCustom() {
//                return new String[]{"Default"};
//            }
//        };
        DataSourceConfig dataSourceConfig = new DataSourceConfig.Builder(
                url,
                username,
                password)
//                .dbQuery(mySqlQuery)//老的代码生成方式，不建议使用，后期不在维护
                .keyWordsHandler(new MySqlKeyWordsHandler())
                .build();

//        7.创建AutoGenerator生成代码，共7个属性(configBuilder无需设置，由其它6个配置组成)
        AutoGenerator generator = new AutoGenerator(dataSourceConfig);
        generator.global(globalConfig)//全局配置
                .template(templateConfig)//模板配置
//                .injection(injectionConfig)//注入配置
                .packageInfo(packageConfig)//包配置
                .strategy(strategyConfig)//策略配置
                //共3个模板引擎 VelocityTemplateEngine、BeetlTemplateEngine、FreemarkerTemplateEngine，默认第一个
                .execute(new FreemarkerTemplateEngine());
    }
}
